-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-5614: Fix deserialization of primitive arrays on Big Endian systems #1683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…imitives for Big Endian support Signed-off-by: Medha Tiwari <[email protected]>
hi @rstam , Can you please review this? |
We will discuss this at our next triage meeting. Not sure whether we intend to support Big Endian systems or not. |
Hi @rstam |
In our other PR (#1682), Boris pointed out that: BinaryPrimitives.ReadSingleBigEndian is not available on older TFMs, i.e. net472 so this won’t compile We added compatibility shims in BinaryPrimitivesCompat for ReadSingleLittleEndian/WriteSingleLittleEndian.
Should we add compatibility shims for these missing cc: @BorisDog |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. Few asks/questions:
-
Could you please file a separate Jira ticket for each PR, describing the issue? And also update the PR name according to our conventions (see the closed PRs for this).
-
Did you observe any failing failing tests without this fix?
@@ -77,6 +78,7 @@ private static T[] ReadBsonArray<T>( | |||
|
|||
var result = new List<T>(); | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for empty lines changes (extra line here, and removed lines below)
@@ -95,85 +97,81 @@ private static T[] ReadBsonArray<T>( | |||
{ | |||
case ConversionType.DoubleToSingle: | |||
{ | |||
var v = (float)BitConverter.ToDouble(bytes, index); | |||
|
|||
var v = (float)BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(bytes.AsSpan(index))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably could just use BinaryPrimitivesCompat.ReadDoubleLittleEndian
?
value = Unsafe.As<float, T>(ref v); | ||
break; | ||
} | ||
case ConversionType.DoubleToDouble: | ||
{ | ||
var v = BitConverter.ToDouble(bytes, index); | ||
var v = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(bytes.AsSpan(index))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we can just work with span instead of bytes in all cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve updated the code to work directly with Span<byte>
instead of using byte[]
where applicable, as you suggested. Please verify and let me know if any further changes are needed.
…stems Signed-off-by: Medha Tiwari <[email protected]>
Hi So I have opened the JIra ticket and I was getting test failures in
|
src/MongoDB.Bson/Serialization/Serializers/PrimitivesArrayReader.cs
Outdated
Show resolved
Hide resolved
src/MongoDB.Bson/Serialization/Serializers/PrimitivesArrayReader.cs
Outdated
Show resolved
Hide resolved
…d2d conversion and reverted extra spaces Signed-off-by: Medha Tiwari <[email protected]>
Thanks @medhatiwari! |
Description
This PR fixes deserialization issues in PrimitivesArrayReader.cs which caused 51 test failures in the MongoDB.Bson.Tests suite on Big Endian systems (e.g., IBM s390x).
Problem
The deserialization logic relied on BitConverter.ToXxx(...) which assumes Little Endian memory layout. On Big Endian architectures, this results in incorrect values for arrays of primitive types such as Int64, Single, Double, and Decimal, leading to test failures.
Fix
Replaced unsafe BitConverter usages with BinaryPrimitives.ReadXxxLittleEndian(...) for endian-safe reads.
Covered conversions for:
Results:
51 test failures resolved.
Example fixed tests:
MemorySerializerTests.ReadonlyMemory_should_roundtrip_special_values<Int64>
MemorySerializerTests.Memory_should_roundtrip_special_values<Single>
BinaryVectorSerializerTests.BinaryVectors_should_roundtrip<float>
Pre-requisites:
s390x system (e.g., IBM Z, RHEL on s390x)
.NET 8.0 SDK installed
cc: @giritrivedi